package com.yand.thinkingInJava.thinkingInJava21.threadcooperation;



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

//膳食
class Meal{
    private int orderNum ;
    public Meal(int orderNum){
        this.orderNum = orderNum;
    }

    public String toString(){
        return "Meal "+orderNum;
    }

}


//服务员
class WaitPerson implements Runnable{

    private Restaurant restaurant;

    public WaitPerson(Restaurant r){
        this.restaurant = r;
    }

    @Override
    public void run() {
        try{
           while(!Thread.interrupted()){
               synchronized (this){
                   //如果餐厅的食物为空则 等待 不进行消费
                   if(restaurant.meal == null){
                         wait();
                   }
               }

               System.out.println("Waitperson got "+restaurant.meal);
               synchronized (restaurant.chef){
                   restaurant.setMealNull();
                   restaurant.chef.notifyAll();
               }
           }
        }catch (InterruptedException e){
            System.out.println("WaitPerson interrupted");
        }

    }
}



class Chef implements Runnable{

    private Restaurant restaurant;
    //计数
    private int count = 0;
    public Chef(Restaurant r){
        this.restaurant = r;
    }

    @Override
    public void run() {
         try{
             while(!Thread.interrupted()){


                //如果食物不为空，则等待 不进行生产
                synchronized (this){
                    if(restaurant.meal != null){
                        wait();
                    }
                }

                if(++count == 10){
                    System.out.println("Out of food, closing");
                    restaurant.exec.shutdownNow();
                }
                System.out.println("Order up! ");
                synchronized (restaurant.waitPerson){
                    restaurant.meal = new Meal(count);
                    //唤醒服务员
                    restaurant.waitPerson.notifyAll();
                }
                 TimeUnit.MILLISECONDS.sleep(100);

             }
         }catch (InterruptedException e){
             System.out.println("Chef interrupted ");
         }
    }
}



/**
 * 餐厅   --- 本例子为生产者消费者 实例 厨师生成食物，服务员上菜
 *
 * 用 wait()/ notify() 方法 需要  synchronized加锁，不可以为同一个对象进行 wait()
 *
 *
 *
 */
public class Restaurant {
    Meal meal;
    ExecutorService exec = Executors.newCachedThreadPool();
    WaitPerson waitPerson = new WaitPerson(this);
    Chef chef = new Chef(this);
    public Restaurant(){
        exec.execute(chef);
        exec.execute(waitPerson);
    }

    public void setMealNull(){
        meal = null;
    }


    public static void main(String [] args){
        new Restaurant();
    }
}
